package com.lysj.bhp.borrowing.service;

import com.lysj.bhp.approve.domain.ApproveRecord;
import com.lysj.bhp.blacklist.domain.Blacklist;
import com.lysj.bhp.borrowing.base.BorrowingContent;
import com.lysj.bhp.borrowing.domain.BorrowingRate;
import com.lysj.bhp.borrowing.domain.BorrowingRecord;
import com.lysj.bhp.util.web.ParamUtil;
import com.lysj.bhp.util.web.Resp;
import com.lysj.bhp.wallet.domain.BhpcWallet;
import com.lysj.bhp.wallet.domain.BitCoinWallet;
import com.lysj.bhp.wallet.domain.EthereumWallet;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Date;

@Service
@Transactional(isolation = Isolation.SERIALIZABLE)
public class BorrowingMoneyService extends BorrowingContent {
    @Transactional(isolation = Isolation.SERIALIZABLE)
    public synchronized Resp applyForBorrowing(BorrowingRecord model, String password) {
        //申请步骤：
        //1.判断用户信息是否完整
        ApproveRecord approveRecord = approveRecordRepository.findByUserId(currentUser().getUserId());
        if (approveRecord == null) {
            return new Resp(3247, "请先完成一级认证", 1);
            //返回信息不完整
        }
        if (approveRecord.getInfoStatus() == 1) {
            return new Resp(3247, "请先完成身份认证信息", 1);
            //返回信息不完整
        }
        //2.先判断是否是黑名单用户
        Blacklist blacklist = blacklistContent.blacklistRepository.findByUserIdAndIsExist(currentUser().getUserId(),1);
        if (blacklist != null) {
            if (blacklist.getOverdueLevel() == 3) {
                return new Resp(200, "操作失败,由于违约严重,您已经无法再使用借贷功能!", 2);
            } else if(blacklist.getOverdueLevel() == 1 || blacklist.getOverdueLevel() == 2) {
                return new Resp(200, "操作失败,由于违约,您的借贷功能被暂停使用!", 2);
            }
            //返回存在在黑名单中
        }
        //3.判断各类信息是否完整
        if (ParamUtil.isBlack(model.getMortgageType())) {
            return new Resp(Resp.PARAM_ERROR, "请选择抵押币种");
        }
        if (model.getInterest().compareTo(BigDecimal.ZERO) <=0) {
            return new Resp(Resp.PARAM_ERROR, "利率有误，操作失败!");
        }
        if (ParamUtil.isBlack(model.getRateType())) {
            return new Resp(Resp.PARAM_ERROR, "请选择利率类型");
        }
        if (ParamUtil.isBlack(model.getBorrowingType())) {
            return new Resp(Resp.PARAM_ERROR, "请输入借款类型");
        }
        if (ParamUtil.isBlack(model.getDeadline())) {
            return new Resp(Resp.PARAM_ERROR, "请输入借款天数");
        }
        if (ParamUtil.isBlack(model.getRefundWay())) {
            return new Resp(Resp.PARAM_ERROR, "请选择还款方式");
        }
        if (null == model.getBorrowingMoney() || new BigDecimal(BigInteger.ZERO).compareTo(model.getBorrowingMoney()) >= 1) {
            return new Resp(Resp.PARAM_ERROR, "请输入借款金额");
        }
        if (ParamUtil.isBlack(password)){
            return new Resp(Resp.PARAM_ERROR, "请输入密码!");
        }
        if (!ParamUtil.md5(password).equals(currentUser().getTradePassword())) {
            return new Resp(Resp.PARAM_ERROR, "交易密码有误!");
        }
        //利率判断
        BorrowingRate borrowingRate = borrowingRateRepository.findByRateTypeAndRepaymentWayAndIsExist(model.getRateType(),model.getRefundWay(),1);
        if(borrowingRate == null){
            borrowingRate = new BorrowingRate();
            borrowingRate.setBorrowingRate(new BigDecimal(30));
        }
        if(borrowingRate.getBorrowingRate().compareTo(model.getInterest()) != 0){
            return new Resp(5927, "官网借款利率发生改变啦,请重新操作!","");
        }
        //借款期限判定
        if (model.getRateType() == 1) {
            if (model.getDeadline() <= 0) {
                return new Resp(Resp.PARAM_ERROR, "操作错误！借款期限需要大于等于1天");
            }
            if (model.getDeadline() > 90) {
                return new Resp(Resp.PARAM_ERROR, "操作错误！最大借款期限只能为90天");
            }
        } else if (model.getRateType() == 2) {
            if (model.getDeadline() <= 0) {
                return new Resp(Resp.PARAM_ERROR, "操作错误,借款期限需要大等于1月");
            }
            if (model.getDeadline() > 3) {
                return new Resp(Resp.PARAM_ERROR, "操作错误！最大借款期限只能为3月");
            }
        }
        //可抵押金额(单位CNY)
        BigDecimal mortgageMoneyCny = mortgageMoneyToCny(model.getMortgageType());
        System.out.println("可抵押金额"+mortgageMoneyCny);
        //借款金额(单位CNY)
        BigDecimal borrowingMoneyCny = changeMoneyUnit(model.getBorrowingMoney(), model.getBorrowingType(), 1);
        //借款金额数量判断:抵押资产10%~50%
        if (borrowingMoneyCny.compareTo(mortgageMoneyCny.multiply(new BigDecimal("0.1"))) <= -1 || borrowingMoneyCny.compareTo(mortgageMoneyCny.multiply(new BigDecimal("0.5"))) >= 1) {
            return new Resp(5927, "申请失败,借款金额为抵押资产的10%~50%","");
        }
        //抵押钱包对应的资产
        BigDecimal mortgageMoney = changeMoneyUnit(borrowingMoneyCny, model.getMortgageType(), 2);
        //实际抵押
        BigDecimal acturalMortgageMoney = mortgageMoney.multiply(new BigDecimal("2"));
        //更改用户钱包可用资产,增加抵押冻结资产
        updateUserWalletBalance(acturalMortgageMoney, model.getMortgageType());
        //5.添加借贷信息
        //传入值部分
        BorrowingRecord borrowingRecord = new BorrowingRecord();
        borrowingRecord.setBorrowingMoney(model.getBorrowingMoney());
        borrowingRecord.setRateType(model.getRateType());
        borrowingRecord.setBorrowingType(model.getBorrowingType());
        borrowingRecord.setDeadline(model.getDeadline());
        borrowingRecord.setRefundWay(model.getRefundWay());
        borrowingRecord.setMortgageType(model.getMortgageType());
        borrowingRecord.setInterest(borrowingRate.getBorrowingRate());
        borrowingRecord.setStatus(1);//修改状态
        borrowingRecord.setUserId(currentUser().getUserId());//添加用户ID
        borrowingRecord.setApplyDate(new Date());//申请时间
        borrowingRecord.setUpdateDate(new Date());//更新时间
        borrowingRecord.setDefaultStatus(2);//是否逾期
        borrowingRecord.setCheckStatus(1);//审核状态
        borrowingRecord.setMortgageMoney(acturalMortgageMoney);//抵押资产
        borrowingRecord.setProgress(0);
        borrowingRecord.setEmail(currentUser().getEmail());
        //添加借贷记录
        borrowingRecord = borrowingRecordRepository.saveAndFlush(borrowingRecord);
        // 生成借款单号 前缀 已经给钱包添加抵押资产
        String prefix = null;
        switch (borrowingRecord.getBorrowingType()) {
            case 10:
                prefix = "BTC";
                break;
            case 20:
                prefix = "ETC";
                break;
            case 100:
                prefix = "BHPC";
                break;
        }
        //后缀
        String suffix = "";
        for (int i = borrowingRecord.getBorrowingRecordId().toString().length(); i < 8; i++) {
            suffix += "0";
        }
        suffix = suffix + borrowingRecord.getBorrowingRecordId();
        borrowingRecord.setBorrowingOrderNo(prefix + "_JK_" + suffix);
        //这边抵押金额应该记录到对应钱包里面去
        borrowingRecordRepository.save(borrowingRecord);
        return new Resp(200, "申请成功!", 4);
    }


    /**
     * @author drj
     * @date 2018/9/2 15:48
     * @Description:改变钱包资产单位: operate:1-对应币种转CNY,2-CNY转对应币种
     */
    public BigDecimal changeMoneyUnit(BigDecimal money, Integer walletType, int operate) {
        BigDecimal acturalMoney = new BigDecimal(BigInteger.ZERO);
        BigDecimal exchangeRate = new BigDecimal("1");
        switch (walletType) {
            case 10:
                exchangeRate = exchangeRateService.bitcoinToCnyRate();
                break;
            case 20:
                exchangeRate = exchangeRateService.ethToCnyRate();
                break;
            case 100:
                exchangeRate = exchangeRateService.bhpcToCnyRate();
                break;
        }
        if (1 == operate) {
            acturalMoney = money.multiply(exchangeRate).setScale(6, BigDecimal.ROUND_HALF_UP);
        } else {
            acturalMoney = money.divide(exchangeRate, 6, BigDecimal.ROUND_HALF_UP);
        }
        return acturalMoney;
    }


    /**
     * @author drj
     * @date 2018/9/2 15:42
     * @Description:可用抵押资产转CNY
     */
    public BigDecimal mortgageMoneyToCny(Integer walletType) {
        BigDecimal mortgageMoneyCny = new BigDecimal(BigInteger.ZERO);
        switch (walletType) {
            case 10:
                BitCoinWallet bitCoinWallet = bitcoinWalletRepository.findByUserId(currentUser().getUserId());
                mortgageMoneyCny = bitCoinWallet.getAvailBalance().multiply(exchangeRateService.bitcoinToCnyRate()).setScale(6, BigDecimal.ROUND_HALF_UP);
                break;
            case 20:
                EthereumWallet ethereumWallet = ethereumWalletRepository.findByUserId(currentUser().getUserId());
                mortgageMoneyCny = ethereumWallet.getAvailBalance().multiply(exchangeRateService.ethToCnyRate()).setScale(6, BigDecimal.ROUND_HALF_UP);
                break;
            case 100:
                BhpcWallet bhpcWallet = bhpcWalletRepository.findByUserId(currentUser().getUserId());
                mortgageMoneyCny = bhpcWallet.getAvailBalance().multiply(exchangeRateService.bhpcToCnyRate()).setScale(6, BigDecimal.ROUND_HALF_UP);
                break;
        }
        return mortgageMoneyCny;
    }


    public void  updateUserWalletBalance(BigDecimal acturalMortgageMoney, Integer mortgageType) {
        BitCoinWallet bitCoinWallet = new BitCoinWallet();
        EthereumWallet ethereumWallet = new EthereumWallet();
        BhpcWallet bhpcWallet = new BhpcWallet();
        switch (mortgageType) {
            case 10:
                bitCoinWallet = bitcoinWalletRepository.findByUserId(currentUser().getUserId());
                bitCoinWallet.setAvailBalance(bitCoinWallet.getAvailBalance().subtract(acturalMortgageMoney));
                bitCoinWallet.setPledgeFreezeBalance(bitCoinWallet.getPledgeFreezeBalance().add(acturalMortgageMoney));
                bitcoinWalletRepository.saveAndFlush(bitCoinWallet);
                break;
            case 20:
                ethereumWallet = ethereumWalletRepository.findByUserId(currentUser().getUserId());
                ethereumWallet.setAvailBalance(ethereumWallet.getAvailBalance().subtract(acturalMortgageMoney));
                ethereumWallet.setPledgeFreezeBalance(ethereumWallet.getPledgeFreezeBalance().add(acturalMortgageMoney));
                ethereumWalletRepository.saveAndFlush(ethereumWallet);
                break;
            case 100:
                bhpcWallet = bhpcWalletRepository.findByUserId(currentUser().getUserId());
                bhpcWallet.setAvailBalance(bhpcWallet.getAvailBalance().subtract(acturalMortgageMoney));
                bhpcWallet.setPledgeFreezeBalance(bhpcWallet.getPledgeFreezeBalance().add(acturalMortgageMoney));
                bhpcWalletRepository.saveAndFlush(bhpcWallet);
                break;
        }
    }


}
